/*
 *
 *   Blah
 *
 */

#include <stdio.h>
#include <stdlib.h>


/* #include <linux/types.h> */

/*
#include <string.h>
#include <signal.h>
*/


#include "foo.h"


/*
typedef union _cell {
  struct {
    uint64_t oct;
  };
  struct {
    uint32_t q1;
    uint32_t q0;
  };
  struct {
    uint16_t w3;
    uint16_t w2;
    uint16_t w1;
    uint16_t w0;
  };
  struct {
    uint8_t b7;
    uint8_t b6;
    uint8_t b5;
    uint8_t b4;
    uint8_t b3;
    uint8_t b2;
    uint8_t b1;
    uint8_t b0;
  };
} cell;
*/


/* typedef struct { */
/*   unsigned long tag: 16; */
/*   unsigned long long body: 48; */
/* } Q; */


/* typedef struct { */
/*   unsigned int gc: 2; */
/*   unsigned int cdrcode: 2; */
/*   unsigned long tag: 12; */
/*   unsigned long long body: 48; */
/* } Q; */

typedef struct Q {
  unsigned int gc: 2;
  unsigned int cdrcode: 2;
  unsigned long tag: 12;
  struct Q *ptr;
} Q, *any;


#define nextq(X) ((Q*)((X)+sizeof(Q)))


Q *NIL;


Q mem[100];


/* typedef unsigned long int addr; */

/* typedef uint64_t Q; */
/* #define qtag(X)    (((X)>>48)&0xFFFF) */
/* #define qbody(X)   ((X)&0xFFFFFFFFFFFF) */

/****************************************************************************


01234567 01234567 01234567 01234567 01234567 01234567 01234567 01234567
######## ######## ######## ######## ######## ######## ######## ########
TTTTTTTT TTTTTTTT AAAAAAAA AAAAAAAA AAAAAAAA AAAAAAAA AAAAAAAA AAAAAAAA
\_______________/ \___________________________________________________/
   16 bit tag                   48 bit pointer or fixint

****************************************************************************/


void err() {
  printf("Argh!\n");
  exit(1);
}


void debug_print_q(Q *q) {
  printf("GC: %x, CDR-code: %x, Tag: %x, Body: %x\n", q->gc, q->cdrcode, q->tag, q->ptr);
  return;
}


Q *car(Q *q) {
  return q->ptr;
}


Q *cdr(Q *q) {
  switch (q->cdrcode) {
    case 0:                                                 /* CDR-NIL */
      return NIL;
      break;
    case 1:
      return nextq(q)->ptr;                                 /* CDR-NORMAL */
      break;
    case 2:                                                 /* CDR-NEXT */
      return nextq(q);
      break;
    case 3:                                                 /* CDR-MISC */
      err();
      break;
  }
  err();
}



int main() {
  
  Q Test, _nil;

  NIL = &_nil;

  
/*   printf("size: %d\n", sizeof(Test)); */
  
  printf("Start.\n");

  debug_print_q(&Test);

  
  
  
  return 0;
}
